/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.core.context;

import com.fasterxml.jackson.annotation.JsonIgnore;
import io.iec.edp.caf.core.session.Session;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * This is {@link BizContext}.
 *
 * @author yisiqi
 * @since 1.0.0
 */
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
public class BizContext<P extends Session> extends Session {
    //2022-06-10由抽象类改为非抽象class，为了支持自定义序列化

    @JsonIgnore
    protected P parent;
    private final Map<String, Object> items;
    @JsonIgnore
    protected BizContextExpirationPolicy expirationPolicy;
    protected String parentId;
    @JsonIgnore
    protected Boolean itemsChanged;
    private String sessionId;

    //无参构造。支持自定义序列化 2022-05-10 上午 09:10
    public BizContext() {
        this.items = new HashMap<>();
        this.itemsChanged = false;
    }

    protected BizContext(String id, ZonedDateTime creationDate, P parent, BizContextExpirationPolicy expirationPolicy) {
        this(id, creationDate, parent, new HashMap<>(), expirationPolicy);
    }

    protected BizContext(String id, ZonedDateTime creationDate, P parent, Map<String, Object> items, BizContextExpirationPolicy expirationPolicy) {
        super(id, creationDate);
        this.parent = parent;
        this.items = items;
        this.expirationPolicy = expirationPolicy;
        if (this.parent != null)
            this.parentId = this.parent.getId();
        this.itemsChanged = false;
    }

    /**
     * 根据键获取值
     *
     * @param key 键
     * @return 值，如果键不存在，则向上查找，如果找不到返回null。
     */
    public Object get(String key) {
        //首先从当前的items中获取，存在则直接返回
        if (this.items != null && this.items.containsKey(key)) {
            return items.get(key);
        }

        //如果parent不为null && parent派生自BizContext，则向上递归查询
        if (this.getParent() != null && BizContext.class.isAssignableFrom(this.getParent().getClass())) {
            BizContext context = (BizContext) this.getParent();
            if (context != null)
                return context.get(key);
        }
        return null;
    }

    /**
     * 添加k-v变量
     *
     * @param key   键
     * @param value 值
     */
    public void put(String key, Object value) {
        if (key != null && !"".equals(key)) {
            this.items.put(key, value);
            this.itemsChanged = true;
        }
    }

    /**
     * 添加k-v变量
     *
     * @param mapItems 键
     */
    public void put(Map<String, Object> mapItems) {
        if (mapItems != null && mapItems.size() > 0) {
            this.getItems().putAll(mapItems);
            this.itemsChanged = true;
        }
    }
}
